--- layout: default ---
import numpy as np
import matplotlib.pyplot as plt
import plotly
import plotly.offline as py
import plotly.graph_objs as go
py.init_notebook_mode()
config={'showLink': False, 'scrollZoom': True}
# Fixing random state for reproducibility
np.random.seed(1)
nbPoints=10
points = np.array( [5*np.arange(nbPoints),5+5*np.arange(nbPoints),5*np.ones(nbPoints)] ).T + 0.5-100*np.random.rand(nbPoints,3)
print(points)
# Step 2: find the mean of the points
avg = np.mean(points, axis=0)
# Step 3: subtract the mean from all points
subtracted = points-avg
# Step 4 : perform SVD
_, _, V = np.linalg.svd(subtracted)
# Step 5: find the direction vector
# (which is the right singular vector corresponding to the largest singular value)
direction = V[0, :]
# Line is 'avg' and 'direction'
p0 = avg;
d = direction;
print(d)
pa = p0 - 50*d
pb = p0 + 50*d
d0 = np.array([0,0,1])
na = p0 + 50*d0
nb = p0 - 50*d0
trace1 = go.Scatter3d(
x=[pa[0],pb[0]],
y=[pa[1],pb[1]],
z=[pa[2],pb[2]],
mode='lines',
name='3D fitted line',
line=go.Line(color='rgb(255,0,0)', width=10),
hoverinfo='none')
trace3 = go.Scatter3d(
x=[na[0],nb[0]],
y=[na[1],nb[1]],
z=[na[2],nb[2]],
mode='lines',
name='normal',
line=go.Line(color='rgb(0,0,255)', width=10),
hoverinfo='none')
labels = []
for i in range(nbPoints): labels += [str(i)]
trace2 = go.Scatter3d(
x=points[:,0],
y=points[:,1],
z=points[:,2],
mode='markers',
name='Points',
marker=go.Marker(
symbol='cross',
opacity=1,
color='rgb(0,200,127)'),
text=labels,
hoverinfo='text')
layout = go.Layout(
title="3D line fitting",
scene=go.Scene(
xaxis=go.XAxis(dict(title="x")),
yaxis=go.YAxis(dict(title="y")),
zaxis=go.ZAxis(dict(title="z")),
camera=dict(
up=dict(x=0, y=0, z=1),
center=dict(x=0, y=0, z=0),
eye=dict(x=0, y=2.5, z=0))))
fig=go.Figure(data=go.Data([trace1, trace2, trace3]), layout=layout)
plotly.plotly.image.ishow(fig)
filedir=py.plot(fig, filename='../posts/figs/line.html', config=config, auto_open=False)
Angle = np.arccos(np.dot(d0,d)/(np.linalg.norm(d0) * np.linalg.norm(d)))
print(Angle*180/np.pi)